package cn.seaboot.admin.file.service;

import cn.seaboot.admin.file.bean.SysFile;
import cn.seaboot.admin.file.dao.FileDao;
import cn.seaboot.admin.starter.upload.StorageName;
import cn.seaboot.admin.upload.Uploader;
import cn.seaboot.admin.upload.OutputInfo;
import cn.seaboot.admin.user.context.UserContext;
import cn.seaboot.commons.core.StringUtils;
import cn.seaboot.commons.file.FilenameUtils;
import cn.seaboot.commons.file.ResponseWriter;
import cn.seaboot.commons.lang.Symbol;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 文件上传
 *
 * <p>
 * 相关联数据需记住文件名，使用文件名下载文件，不以ID作为查询关键字
 * <p>
 * 可用，业务需要进一步拆分
 *
 * @author ChenSS on 2018/6/21.
 */
@Service
public class FileService {

    @Resource
    private FileDao fileDao;

    @Resource
    private UserContext userContext;

    /**
     * 保存一份文件，并将数据保存到数据库
     *
     * @param type          数据类型
     * @param multipartFile 文件实体
     * @return 文件存储信息
     * @throws IOException -
     */
    public SysFile saveFile(String type, MultipartFile multipartFile) throws IOException {
        String ex = FilenameUtils.getExtension(multipartFile.getOriginalFilename());

        OutputInfo info = Uploader.storage(StorageName.FILE).write(multipartFile);
        SysFile file = new SysFile();
        // 归属
        String filename = info.getName() + "." + ex;

        file.setId(filename);
        file.setOrgId(userContext.getOrgId());
        file.setUserId(userContext.getUserId());

        // 信息要素
        file.setFileType(type);
        file.setFileSize(multipartFile.getSize());
        file.setFilePath(info.getPath());

        String fileName = multipartFile.getOriginalFilename();
        if (fileName == null) {
            fileName = file.getId() + Symbol.PERIOD + file.getExtension();
        }
        file.setFileName(StringUtils.truncateHead(fileName, 64));
        file.setExtension(ex);

        file.setGmtCreate(LocalDateTime.now());
        fileDao.insert(file);
        return file;
    }

    /**
     * 按ID删除
     *
     * @param id ID
     * @return affected rows
     */
    public int deleteById(String id) throws IOException {
        SysFile file = fileDao.selectById(id);
        int res = fileDao.deleteById(id);
        Uploader.storage(StorageName.FILE).delete(file.getFilePath());
        return res;
    }

    /**
     * 打开文件输入流
     *
     * @param id 文件ID
     * @throws IOException -
     */
    public InputStream openInputStream(String id) throws IOException {
        SysFile file = fileDao.selectById(id);
        if (file == null) {
            throw new FileNotFoundException("file not found: " + id);
        } else {
            return Uploader.storage(StorageName.FILE).openInputStream(file.getFilePath());
        }
    }


    /**
     * 打开文件输入流
     *
     * @param id 文件ID
     * @throws IOException -
     */
    public void download(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        SysFile file = fileDao.selectById(id);
        if (file == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            String name = file.getId() + Symbol.PERIOD + file.getExtension();
            try (InputStream inputStream = Uploader.storage(StorageName.FILE).openInputStream(name)) {
                ResponseWriter.download(response, inputStream, name);
            }
        }
    }


    /**
     * 预览文件，有浏览器默认插件打开，文本
     *
     * @param id 文件ID
     * @throws IOException -
     */
    public void preview(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        SysFile file = fileDao.selectById(id);
        if (file == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        } else {
            try (InputStream inputStream = Uploader.storage(StorageName.FILE).openInputStream(file.getFilePath())) {
                String name = file.getFileName() + Symbol.PERIOD + file.getExtension();
//                if (ResponseWriter.canPreview(file.getExtension())) {
                // TODO: 可预览图片识别

                ResponseWriter.preview(response, inputStream, name);
//                } else {
//                    ResponseWriter.create(request, response).setNoCache().setDownloadName(name).write(inputStream);
//                }
            }
        }
    }

    /**
     * 根据当前登录账号查询图片列表
     *
     * @return 图片列表
     */
    public List<SysFile> queryList(Map<String, Object> params) {
        return fileDao.selectList(params);
    }

    /**
     * 按ID查询
     *
     * @param id ID
     * @return pojo
     */
    public SysFile queryById(String id) {
        return fileDao.selectById(id);
    }
}
